package user

import (
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	jwt "github.com/star-find-cloud/star-chat/pkg/jwt"
	log "github.com/star-find-cloud/star-chat/pkg/logger"
	"github.com/star-find-cloud/star-chat/user/domain"
	"github.com/star-find-cloud/star-chat/user/dto"
	"github.com/star-find-cloud/star-chat/user/service"
	"github.com/star-find-cloud/star-chat/utils"
)

type UserHandler struct {
	service service.UserService
}

func NewUserHandler(service service.UserService) *UserHandler {
	return &UserHandler{
		service: service,
	}
}

// Create 创建用户, 测试专用接口
// @Summary 创建用户
// @Description 创建一个新的用户账户，用于测试目的
// @Tags 用户
// @Accept  json
// @Produce  json
// @Param user body dto.RegisterUserReq true "用户信息"
// @Success 200 {object} utils.Response id
// @Failure 400 {object} utils.Response "request parameter error"
// @Failure 500 {object} utils.Response "internal server error"
// @Router /api/v1/user/create [post]
func (h *UserHandler) Create(c *gin.Context) {
	var req = &dto.RegisterUserReq{}
	if err := c.ShouldBind(req); err != nil {
		log.HttpLogger.Errorf("request error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "request parameter error", err)
		return
	}

	user := &domain.User{}
	if err := utils.ConversionStructForJson(req, user); err != nil {
		log.AppLogger.Errorf("conversion json error: %v", err)
	}

	id, err := h.service.Create(c, user)
	if err != nil {
		utils.RespondError(c, http.StatusInternalServerError, "internal server error", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, id)
	return
}

func (h *UserHandler) Register(c *gin.Context) {
	var req = &dto.RegisterUserReq{}
	if err := c.ShouldBind(req); err != nil {
		log.HttpLogger.Errorf("request error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "请求参数错误", err)
		return
	}

	exist, err := h.service.CheckEmailVerificationCode(c, req.Email, req.VerificationCode)
	if err != nil || !exist {
		utils.RespondError(c, http.StatusBadRequest, "verification code err", err)
		return
	}

	user := &domain.User{}
	if err := utils.ConversionStructForJson(req, user); err != nil {
		log.AppLogger.Errorf("conversion json error: %v", err)
	}

	token, id, err := h.service.Register(c, user)
	if err != nil {
		utils.RespondError(c, http.StatusInternalServerError, "服务器内部错误", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, &dto.RegisterUserResp{
		ID:    id,
		Token: token,
	})
	return
}

// Get 获取用户信息
func (h *UserHandler) Get(c *gin.Context) {

}

func (h *UserHandler) Login(c *gin.Context) {
	var req dto.LoginUserReq
	if err := c.ShouldBindJSON(&req); err != nil {
		log.HttpLogger.Errorf("login request bind error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "请求参数错误", err)
		return
	}

	var user *domain.User
	var err error

	// 根据登录类型调用不同的service方法
	switch req.LoginType {
	case "name":
		// 用户名登录暂不支持，需要先实现GetByName方法
		utils.RespondError(c, http.StatusBadRequest, "用户名登录暂不支持", nil)
		return
	case "email":
		user, err = h.service.Login(c, 0, 0, 0, req.Identifier, req.Password)
	case "phone":
		// 这里需要解析手机号，暂时使用默认国家码86
		user, err = h.service.Login(c, 0, 0, 86, "", req.Password)
	default:
		utils.RespondError(c, http.StatusBadRequest, "不支持的登录类型", nil)
		return
	}

	if err != nil {
		log.HttpLogger.Errorf("login failed: %v", err)
		utils.RespondError(c, http.StatusUnauthorized, "登录失败", err)
		return
	}

	// 生成JWT token
	token, err := jwt.GenerateToken(user.ID, user.Name, 1)
	if err != nil {
		log.AppLogger.Errorf("generate token failed: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "服务器内部错误", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, dto.LoginUserResp{
		ID:       user.ID,
		Name:     user.Name,
		Email:    user.Email,
		Phone:    user.Phone,
		Token:    token,
		AvatarID: user.Avatar,
	})
}

func (h *UserHandler) GetByID(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		utils.RespondJSON(c, http.StatusBadRequest, dto.ErrorResp{Code: http.StatusBadRequest, Message: "Invalid ID"})
		return
	}

	user, err := h.service.GetByID(c, id)
	if err != nil {
		log.HttpLogger.Errorf("get user by id failed: %v", err)
		utils.RespondError(c, http.StatusNotFound, "用户不存在", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, dto.UserInfoResp{
		ID:         user.ID,
		Name:       user.Name,
		NickName:   user.NickName,
		Email:      user.Email,
		Phone:      user.Phone,
		Sex:        user.Sex,
		Avatar:     user.Avatar,
		Status:     user.Status,
		VipStatus:  user.VipStatus,
		CreateTime: user.CreateTime,
		UpdateTime: user.UpdateTime,
	})
}

func (h *UserHandler) GetByEmail(c *gin.Context) {
	email := c.Param("email")
	if email == "" {
		utils.RespondError(c, http.StatusBadRequest, "邮箱不能为空", nil)
		return
	}

	user, err := h.service.GetByEmail(c, email)
	if err != nil {
		log.HttpLogger.Errorf("get user by email failed: %v", err)
		utils.RespondError(c, http.StatusNotFound, "用户不存在", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, dto.UserInfoResp{
		ID:         user.ID,
		Name:       user.Name,
		NickName:   user.NickName,
		Email:      user.Email,
		Phone:      user.Phone,
		Sex:        user.Sex,
		Avatar:     user.Avatar,
		Status:     user.Status,
		VipStatus:  user.VipStatus,
		CreateTime: user.CreateTime,
		UpdateTime: user.UpdateTime,
	})
}



func (h *UserHandler) GetByPhone(c *gin.Context) {
	phoneStr := c.Param("phone")
	phone, err := strconv.ParseInt(phoneStr, 10, 64)
	if err != nil {
		utils.RespondError(c, http.StatusBadRequest, "参数错误", err)
		return
	}

	user, err := h.service.GetByPhone(c, phone)
	if err != nil {
		log.HttpLogger.Errorf("get user by phone failed: %v", err)
		utils.RespondError(c, http.StatusNotFound, "用户不存在", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, dto.UserInfoResp{
		ID:         user.ID,
		Name:       user.Name,
		NickName:   user.NickName,
		Email:      user.Email,
		Phone:      user.Phone,
		Sex:        user.Sex,
		Avatar:     user.Avatar,
		Status:     user.Status,
		VipStatus:  user.VipStatus,
		CreateTime: user.CreateTime,
		UpdateTime: user.UpdateTime,
	})
}

func (h *UserHandler) Update(c *gin.Context) {
	var req dto.UpdateUserReq
	if err := c.ShouldBindJSON(&req); err != nil {
		log.HttpLogger.Errorf("update user bind error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "请求参数错误", err)
		return
	}

	user := &domain.User{}
	if err := utils.ConversionStructForJson(req, user); err != nil {
		log.AppLogger.Errorf("conversion json error: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "服务器内部错误", err)
		return
	}

	err := h.service.Update(c, user)
	if err != nil {
		log.HttpLogger.Errorf("update user failed: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "更新用户失败", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, &dto.SuccessResp{
		Success: true,
		Message: "用户更新成功",
	})
}

func (h *UserHandler) UpdatePassword(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		utils.RespondError(c, http.StatusBadRequest, "参数错误", err)
		return
	}

	var req struct {
		OldPassword string `json:"oldPassword"`
		NewPassword string `json:"newPassword"`
	}
	
	if err := c.ShouldBindJSON(&req); err != nil {
		log.HttpLogger.Errorf("update password bind error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "请求参数错误", err)
		return
	}

	err = h.service.UpdatePassword(c, id, req.OldPassword, req.NewPassword)
	if err != nil {
		log.HttpLogger.Errorf("update password failed: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "更新密码失败", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, &dto.SuccessResp{
		Success: true,
		Message: "密码更新成功",
	})
}

func (h *UserHandler) UpdatePhone(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		utils.RespondError(c, http.StatusBadRequest, "参数错误", err)
		return
	}

	var req struct {
		CountryCode int64 `json:"countryCode"`
		Phone       int64 `json:"phone"`
	}
	
	if err := c.ShouldBindJSON(&req); err != nil {
		log.HttpLogger.Errorf("update phone bind error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "请求参数错误", err)
		return
	}

	err = h.service.UpdatePhone(c, id, req.CountryCode, req.Phone)
	if err != nil {
		log.HttpLogger.Errorf("update phone failed: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "更新手机号失败", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, &dto.SuccessResp{
		Success: true,
		Message: "手机号更新成功",
	})
}

func (h *UserHandler) ForgetPassword(c *gin.Context) {
	var req struct {
		Email    string `json:"email"`
		Phone    int64  `json:"phone"`
		Password string `json:"password"`
		Code     string `json:"code"`
	}
	
	if err := c.ShouldBindJSON(&req); err != nil {
		log.HttpLogger.Errorf("forget password bind error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "请求参数错误", err)
		return
	}

	// 验证验证码（这里需要实现验证码验证逻辑）
	// 暂时跳过验证码验证

	err := h.service.ForgetPassword(c, req.Phone, req.Email, req.Password)
	if err != nil {
		log.HttpLogger.Errorf("forget password failed: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "重置密码失败", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, &dto.SuccessResp{
		Success: true,
		Message: "密码重置成功",
	})
}

// BannedUser 封禁用户
func (h *UserHandler) BannedUser(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		utils.RespondError(c, http.StatusBadRequest, "参数错误", err)
		return
	}

	var req struct {
		BannedTime int64 `json:"bannedTime"` // 封禁时长（秒）
	}
	
	if err := c.ShouldBindJSON(&req); err != nil {
		log.HttpLogger.Errorf("banned user bind error: %v", err)
		utils.RespondError(c, http.StatusBadRequest, "请求参数错误", err)
		return
	}

	// 将秒数转换为time.Time
	bannedUntil := time.Now().Add(time.Duration(req.BannedTime) * time.Second)
	
	err = h.service.BannedUser(c, id, bannedUntil)
	if err != nil {
		log.HttpLogger.Errorf("banned user failed: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "封禁用户失败", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, &dto.SuccessResp{
		Success: true,
		Message: "用户封禁成功",
	})
}

func (h *UserHandler) Delete(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		utils.RespondError(c, http.StatusBadRequest, "参数错误", err)
		return
	}

	err = h.service.Delete(c, id)
	if err != nil {
		log.HttpLogger.Errorf("delete user failed: %v", err)
		utils.RespondError(c, http.StatusInternalServerError, "删除用户失败", err)
		return
	}

	utils.RespondJSON(c, http.StatusOK, &dto.SuccessResp{
		Success: true,
		Message: "用户删除成功",
	})
}
